package JavaUtils.CSUtils.Log;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import JavaUtils.CSUtils.CString;
import JavaUtils.interfaceType.ILog;

public class CLogTxtSave implements ILog {
    public String deviceInfo;
    long msgIndex;
    long fileIndex;
    String prefixPath;
    String fileName;
    String _saveFullPath;
    String onlyName;
    boolean isRealtimeSave;

    BufferedWriter bw = null;
    StringBuilder ssb = new StringBuilder();

    public String o_saveFullPath() {
        return _saveFullPath;
    }

    static List<CLogTxtSave> o_localLogs = new ArrayList<CLogTxtSave>();

    public CLogTxtSave(boolean isRealtimeSave, String deviceInfo, String prefixPath) {
        this.isRealtimeSave = isRealtimeSave;
        if (prefixPath == null) {
//             prefixPath = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
//             prefixPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);    		 
            prefixPath = System.getProperty("user.dir");
        }
        o_localLogs.add(this);
        deviceInfo = deviceInfo.replace("\\", "");
        deviceInfo = deviceInfo.replace("/", "");
        deviceInfo = deviceInfo.replace(":", "");
        deviceInfo = deviceInfo.replace("?", "");
        deviceInfo = deviceInfo.replace("*", "");
        deviceInfo = deviceInfo.replace("\"", "");
        deviceInfo = deviceInfo.replace("<", "");
        deviceInfo = deviceInfo.replace(">", "");
        this.deviceInfo = deviceInfo;
        this.prefixPath = prefixPath;
        Date date = new Date();
        onlyName = new SimpleDateFormat("HH.mm.ss").format(date);
        fileName = String.format("%s/%s", deviceInfo, new SimpleDateFormat("yyyy年MM月dd号/HH点mm分ss秒").format(date));

        S_CreateFile();
    }

    int maxMsgNumberLimit = 4000;

    void S_CreateFile() {
        fileIndex = msgIndex / maxMsgNumberLimit;
        _saveFullPath = String.format("%s/logList/%s_%d.html", prefixPath, fileName, fileIndex);

        ssb.delete(0, ssb.length());
        ssb.append(String.format("<html>\r\n<title>log.%s</title>\r\n<body bgcolor='#222222'>\r\n", onlyName));
        String htmlFileHeaderStr =
                "<head>\r\n"
                        + "   <meta charset='UTF-8'>\n"
                        + "     <style>\n"
                        + "        body {\n"
                        + "            margin: 0 auto;\n"
                        + "            width: 10000px;\n"
                        + "            height: 1000px;\n"
                        + "            background-color: #002222;\n"
                        + "        }\n"
                        + "\n"
                        + "        .log {\n"
                        + "            font-size: 1px;\n"
                        + "            color: #609940;\n"
                        + "        }\n"
                        + "\n"
                        + "        .err {\n"
                        + "            font-size: 1px;\n"
                        + "            color: #990022;\n"
                        + "            background-color: #220000;\n"
                        + "        }\n"
                        + "\n"
                        + "        .ass {\n"
                        + "            font-size: 1px;\n"
                        + "            color: #9999bb;\n"
                        + "        }\n"
                        + "\n"
                        + "        .war {\n"
                        + "            font-size: 1px;\n"
                        + "            color: #999900;\n"
                        + "            background-color: #444400;\n"
                        + "        }\n"
                        + "\n"
                        + "            .ex {\n"
                        + "            font-size: 1px;\n"
                        + "            color: #ff00ff;\n"
                        + "            background-color: #880088;\n"
                        + "        }\n"
                        + "\n"
                        + "            .st {\n"
                        + "            font-size: 1px;\n"
                        + "            color: #006060;\n"
                        + "        }\n"
                        + "\n"
                        + "        .btn {\n"
                        + "            z-index: 999; /*一个很大的层，保证不被其他元素覆盖*/\n"
                        + "            position: fixed;\n"
                        + "            top: 0; /*如果不是置顶，这里可以设置具体位置*/\n"
                        + "        }\n"
                        + "    </style>\n"
                        + "        <script type='text/javascript'>\n"
                        + "                window.onload = function () {\n"
                        + "            var fonts = document.getElementsByTagName('font');\n"
                        + "            for (var i = 0, j = fonts.length; i < j; i++) {\n"
                        + "                var fontObj = fonts[i];\n"
                        + "                if (fontObj.className == 'st') {\n"
                        + "                    fontObj.style.display = 'none';\n"
                        + "                } else {\n"
                        + "                    fontObj.style.display = 'block';\n"
                        + "                    fontObj.onclick = function () {\n"
                        + "                        var next = this.nextElementSibling;\n"
                        + "                        if (next.style.display == 'none') {\n"
                        + "                            next.style.display = 'block';\n"
                        + "                        } else {\n"
                        + "                            next.style.display = 'none';\n"
                        + "                        }\n"
                        + "                    }\n"
                        + "                }\n"
                        + "            }\n"
                        + "            var exBtn = document.getElementById('exBtn');\n"
                        + "            exBtn.isHideOther = false;\n"
                        + "            exBtn.onclick = function () {\n"
                        + "                exBtn.isHideOther = !exBtn.isHideOther;\n"
                        + "                exBtn.innerText = exBtn.isHideOther ? '显示全部log' : '只显示异常log';\n"
                        + "                for (var i = 0, j = fonts.length; i < j; i++) {\n"
                        + "                    var fontObj = fonts[i];\n"
                        + "                    if (exBtn.isHideOther) {\n"
                        + "                        if (fontObj.className == 'ex' || fontObj.className == '_ex') {\n"
                        + "                            fontObj.style.display = 'block';\n"
                        + "                        } else {\n"
                        + "                            fontObj.style.display = 'none';\n"
                        + "                        }\n"
                        + "                    } else {\n"
                        + "                        if (fontObj.className == 'st') {\n"
                        + "                            fontObj.style.display = 'none';\n"
                        + "                        } else {\n"
                        + "                            fontObj.style.display = 'block';\n"
                        + "                        }\n"
                        + "                    }\n"
                        + "                }\n"
                        + "            }\n"
                        + "        }\n"
                        + "        </script>\n"
                        + "    </head>\n"
                        + "    <body>\n"
                        + "        <button class='btn' id='exBtn'>只显示异常log</button>\n"
                        + "        <br/><br/>\n"
                        + "                \n";
        ssb.append(htmlFileHeaderStr);
        ssb.append(String.format("<font size = '3' color = '#00bb88' > %s </font><br/>\r\n", fileName));
        ssb.append("\t\t<font class='st'> 0> <br/></font>\r\n\r\n");
        try {
            File fi = new File(_saveFullPath);
            if (fi.exists() == false) {
                if (fi.getParentFile().exists() == false) {
                    fi.getParentFile().mkdirs();
                }
                fi.createNewFile();
            }
            FileOutputStream fiou = new FileOutputStream(fi, true);
            OutputStreamWriter opw = new OutputStreamWriter(fiou, "UTF-8");
            bw = new BufferedWriter(opw);
        } catch (Exception e) {
            System.err.println("log保存失败.....: " + e.getMessage() + "...\n" + CLog.S_GetInfo(e));
        }
        S_Writer(ssb.toString());
    }

    @Override
    public void AddLog(byte msgType, String tag, String currTime, String logStr, String stackTrace) {
        int index = logStr.indexOf('\n');
        if (index > 0) {
            stackTrace = logStr.substring(index) + "\n" + stackTrace;
            logStr = logStr.substring(0, index);
        }
        if (CString.IsNullOrEmpty(tag) == false) {
            logStr = tag + "..........." + logStr;
        }
        long ff = msgIndex / maxMsgNumberLimit;
        if (fileIndex != ff) {
            S_CreateFile();
        }
        if (isRealtimeSave) {
            StringBuilder ssb = new StringBuilder();
            _ToLogStr(msgType, currTime, logStr, msgIndex++, stackTrace, ssb);
            S_Writer(ssb.toString());
        } else {
            MLog logObj = new MLog();
            logObj.msgIndex = msgIndex++;
            logObj.msgType = msgType;
            logObj.time = currTime;
            logObj.logStr = logStr;
            logObj.stackTrace = stackTrace;

            logList.add(logObj);
            if (logList.size() > 300) {
                SaveData();
            }
        }
    }

    List<MLog> logList = new ArrayList<>();

    public static void S_SaveData() {
        for (int i = 0; i < o_localLogs.size(); i++) {
            CLogTxtSave mm = o_localLogs.get(i);
            mm.SaveData();
            System.out.println("log保存成功: " + mm._saveFullPath);
        }
    }

    public static void S_ClearAll() {
        for (int i = 0; i < o_localLogs.size(); i++) {
            o_localLogs.get(0).S_Clear();
            i--;
        }
    }

    public void S_Clear() {
        try {
            SaveData();
            bw.flush();
            o_localLogs.remove(0);
        } catch (Exception ex) {
            System.err.printf("错误.....保存失败");
            ex.fillInStackTrace();
        }
    }

    void SaveData() {
        ssb.delete(0, ssb.length());
        for (int i = 0; i < logList.size(); i++) {
            MLog logObj = logList.get(i);
            _ToLogStr(logObj.msgType, logObj.time, logObj.logStr, logObj.msgIndex, logObj.stackTrace, ssb);
        }
        //ssb.AppendFormat("</body>\r\n</html>");
        S_Writer(ssb.toString());
        //CLog.LogError("S_SaveData---------------------" + logList.Count);
        logList.clear();
    }

    void _ToLogStr(byte msgType, String time, String logStr, long msgIndex, String stackTrace, StringBuilder ssb) {
        String[] sss = CString.S_GetLogColor(logStr);
        String color = sss[0];
        logStr = sss[1];
        switch (msgType) {
            case 0://Error
                if (color != null) {
                    ssb.append(String.format("\t<font class='_err' size = '1' color = '#%s' style='background-color:#220000' > %d>---%s<br/></font>\n", color, msgIndex, logStr));
                } else {
                    ssb.append(String.format("\t<font class='err' > %d>---%s<br/></font>\r\n", msgIndex, logStr));
                }
                break;
            case 1://Assert
                if (color != null) {
                    ssb.append(String.format("\t<font class='_ass' size = '1' color = '#%s' > %d>---%s<br/></font>\n", color, msgIndex, logStr));
                } else {
                    ssb.append(String.format("\t<font class='ass' > %d>---%s<br/></font>\r\n", msgIndex, logStr));
                }
                break;
            case 2://Warning
                if (color != null) {
                    ssb.append(String.format("\t<font class='_war' size = '1' color = '#%s' style='background-color:#444400' > %d>---%s<br/></font>\n", color, msgIndex, logStr));
                } else {
                    ssb.append(String.format("\t<font class='war' > %d>---%s<br/></font>\r\n", msgIndex, logStr));
                }
                break;
            case 3://Log
                if (color != null) {
                    ssb.append(String.format("\t<font class='_log' size = '1' color = '#%s' > %d>---%s<br/></font>\n", color, msgIndex, logStr));
                } else {
                    ssb.append(String.format("\t<font class='log' > %d>---%s<br/></font>\r\n", msgIndex, logStr));
                }
                break;
            case 4://Exception
            case 5://Exception
                if (color != null) {
                    ssb.append(String.format("\t<font class='_ex' size = '1' color = '#%s' style='background-color:#880088' > %d>---%s<br/></font>\r\n", color, msgIndex, logStr));
                } else {
                    ssb.append(String.format("\t<font class='ex' > %d>---%s<br/></font>\r\n", msgIndex, logStr));
                }
                break;
        }
        ssb.append(String.format("\t\t<font class='st'> %s===>%s<br/></font>\r\n", time, stackTrace.replace("\n", "<br>")));
    }

    ///
    BufferedWriter S_Writer(String ss) {
        try {
            bw.newLine();
            bw.write(ss);
            bw.flush();
        } catch (Exception e) {
            System.err.println("log保存失败.....: " + e.getMessage() + "...\n" + CLog.S_GetInfo(e));
        }
        return bw;
    }
}


class MLog {
    public byte msgType;
    public long msgIndex;
    public String logStr, stackTrace, time;
}

